package com.kun.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.lang.tree.parser.NodeParser;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kun.entity.SysMenu;
import com.kun.entity.SysPermission;
import com.kun.entity.SysTenantPackage;
import com.kun.entity.SysUser;
import com.kun.enums.MenuTypeEnums;
import com.kun.mapper.SysMenuMapper;
import com.kun.mapper.SysTenantMapper;
import com.kun.mapper.SysTenantPackageMapper;
import com.kun.mapper.SysUserMapper;
import com.kun.service.SysMenuService;
import com.kun.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author kun.li
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysTenantMapper sysTenantMapper;

    @Autowired
    private SysTenantPackageMapper sysTenantPackageMapper;


    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public List<SysPermission> selectPermission(Integer menuType, String tenantId, String userId) {
        /*
          根据用户ID获取用户是否是平台管理员 如果是 则拥有全部菜单权限
          否则 只拥有该用户权限
         */
        SysUser sysUser = sysUserMapper.selectByIdIgnore(userId, tenantId);
        if (ObjectUtil.isNotNull(sysUser) && sysUser.getHasAdmin() == 0) {
            return sysMenuMapper.selectPermissionSuperAdmin(menuType, userId);
        }
        return sysMenuMapper.selectPermission(menuType, userId, tenantId);
    }


    @Override
    public Map<String, Object> getRoute(String tenantId, String userId) {
        SysUser sysUser = sysUserMapper.selectByIdIgnore(userId, tenantId);
        List<SysMenu> menuList;
        // 超级用户获取全部菜单
        // 其他用户获取租户相关菜单
        if (sysUser.getHasAdmin() == 0) {
            LambdaQueryWrapper<SysMenu> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(SysMenu::getMenuType, MenuTypeEnums.MENU.getMenuType());
            menuList = sysMenuMapper.selectList(queryWrapper);
        } else {
            menuList = sysMenuMapper.selectTenantMenuList(MenuTypeEnums.MENU.getMenuType(), tenantId, userId);
        }
        if (CollUtil.isNotEmpty(menuList)) {
            // 得到树形结构
            List<Tree<String>> treeListS = TreeUtil.build(menuList, "-1", extraNode());
            // 获取首页
            String home = menuList.stream().filter(sysMenu -> sysMenu.getHasHome() == 0)
                    .map(SysMenu::getName)
                    .toList().get(0);
            Map<String, Object> resultRouteMap = new HashMap<>();
            resultRouteMap.put("routes", treeListS);
            resultRouteMap.put("home", home);
            return resultRouteMap;
        }
        return new HashMap<>();
    }

    @Override
    public List<SysMenu> getMenuListByRoelId(String roleId) {
        return sysMenuMapper.selectListByRoleList(roleId);
    }

    @Override
    public List<SysMenu> selectMenuList(SysUser sysUser, String menuName) {
        Integer hasAdmin = sysUser.getHasAdmin();
        List<SysMenu> sysMenuList;
        // 超级用户
        if (hasAdmin == 0) {
            LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StrUtil.isNotEmpty(menuName), SysMenu::getMenuName, menuName);
            sysMenuList = sysMenuMapper.selectList(queryWrapper);
        } else {
            sysMenuList = sysMenuMapper.selectMenuListByUserId(sysUser.getUserId());
        }
        return sysMenuList;
    }

    @Override
    public List<String> selectMenuListByPackageId(String packageId) {
        SysTenantPackage tenantPackage = sysTenantPackageMapper.selectById(packageId);
        List<String> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toStr);
        if (CollUtil.isEmpty(menuIds)) {
            return List.of();
        }
        return menuIds;
    }


    private NodeParser<SysMenu, String> extraNode() {
        return (sysMenu, treeNode) -> {
            treeNode.setWeight(sysMenu.getWeight());
            treeNode.setId(sysMenu.getMenuId());
            treeNode.setParentId(sysMenu.getParentId());
            treeNode.setName(sysMenu.getName());
            treeNode.putExtra("path", sysMenu.getPath());
            treeNode.putExtra("component", sysMenu.getComponent());
            String redirect = sysMenu.getRedirect();
            if (StrUtil.isNotEmpty(redirect)) {
                treeNode.putExtra("redirect", sysMenu.getRedirect());
            }
            Map<String, Object> meta = MapUtil.newHashMap();
            meta.put("title", sysMenu.getMenuName());
            meta.put("requiresAuth", sysMenu.getRequiresAuth() == 0);
            meta.put("order", sysMenu.getWeight());
            String icon = sysMenu.getIcon();
            if (StrUtil.isNotEmpty(icon)) {
                meta.put("icon", icon);
            }
            treeNode.putExtra("meta", meta);
        };
    }
}
